package service

import (
	"encoding/json"
	"errors"
	"github.com/e421083458/gin_scaffold/public"
	"github.com/e421083458/gorm"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"github.com/gogf/gf/os/glog"
	"rock/customer/dto"
	"rock/customer/initParam"
	"rock/customer/models"
	"rock/customer/modules/cacheMap"
	"rock/customer/modules/redisModules"
	"rock/customer/modules/taskMap"
	"time"
)

type Group struct {
}

// 群
func (g *Group) Group(gc *gin.Context, tx *gorm.DB, groupId string) (data models.WkbGroup, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.GroupPrefix + groupId)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return data, err
		}
	}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbGroup{}).Where("group_id = ?", groupId).First(&data).Error
	if err != nil {
		return
	}
	if data.GroupID == "" {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.GroupPrefix+groupId, 3*24*time.Hour)
	return
}

// 群 - 更新群最新消息
func (g *Group) UpdateGroupLastChat(gc *gin.Context, tx *gorm.DB, groupId string, lastChatId int, lastFromUserId string, lastObjectName string, lastContentText string, lastChatTime time.Time) error {
	return tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbGroup{}).
		Where("group_id = ?", groupId).
		Update("last_chat_id", lastChatId).
		Update("last_from_user_id", lastFromUserId).
		Update("last_object_name", lastObjectName).
		Update("last_content_text", lastContentText).
		Update("last_chat_time", lastChatTime).
		Error
}

// 群 - 双方都在的私聊群
func (g *Group) GroupCs(gc *gin.Context, tx *gorm.DB, userId string, otherUserId string) (data models.WkbGroup, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.GroupMemberCsPrefix + "u_" + userId + "_ou_" + otherUserId)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	// 查db
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbGroup{}).
		Where("((user_id = ? and other_user_id = ?) or (other_user_id = ? and user_id = ?)) and group_type = 2", userId, otherUserId, userId, otherUserId).
		Find(&data).Error
	if err != nil {
		if err.Error() != gorm.ErrRecordNotFound.Error() {
			err = errors.New(initParam.DataIsNotExist)
			return
		}
	}
	if data.ID == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.GroupMemberCsPrefix+"u_"+userId+"_ou_"+otherUserId, 3*24*time.Hour)
	return
}

// 群 - 双方都在的群聊群
func (g *Group) GroupC(gc *gin.Context, tx *gorm.DB, userId string, otherUserId string) (data models.WkbGroup, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.GroupMemberCPrefix + "u_" + userId + "_ou_" + otherUserId)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	// 查db
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbGroup{}).
		Where("((user_id = ? and other_user_id = ?) or (other_user_id = ? and user_id = ?)) and group_type = 1", userId, otherUserId, userId, otherUserId).
		Find(&data).Error
	if err != nil {
		if err.Error() != gorm.ErrRecordNotFound.Error() {
			err = errors.New(initParam.DataIsNotExist)
			return
		}
	}
	if data.ID == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.GroupMemberCPrefix+"u_"+userId+"_ou_"+otherUserId, 3*24*time.Hour)
	return
}

// 群 - 该用户在群内
func (g *Group) UserInGroup(gc *gin.Context, tx *gorm.DB, groups []string, userId string) (data []dto.GroupRongCloudInfo, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.GroupMemberInGroupPrefix + "u_" + userId)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	// 查db
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbGroup{}).
		Where("group_id IN (?) and user_id = ? and other_user_id = 0 and group_type = 1", groups, userId).
		Scan(&data).Error
	if err != nil {
		if err.Error() != gorm.ErrRecordNotFound.Error() {
			err = errors.New(initParam.DataIsNotExist)
			return
		}
	}
	if len(data) == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.GroupMemberInGroupPrefix+"u_"+userId, 3*24*time.Hour)
	return
}

// 群 - 创建
func (g *Group) CreateGroup(gc *gin.Context, tx *gorm.DB, group *models.WkbGroup) error {
	cr := tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbGroup{}).Create(group)
	return cr.Error
}

// 群 - 修改状态
func (g *Group) UpdateGroupState(gc *gin.Context, tx *gorm.DB, groupId string, state int) error {
	if state > 1 {
		keyCustomer := groupId + "_customer"
		taskMap.M.Remove(keyCustomer)
		keyCustomerService := groupId + "_customerService"
		taskMap.M.Remove(keyCustomerService)
		redisModules.RedisSendGroupWelcomeText("set", "SendGroupWelcomeText_"+groupId, 0)
		redisModules.RedisSendIntroductionText("set", "SendIntroductionText_"+groupId, 0)
		cacheMap.GroupMember.Remove(groupId)
		err := g.UpdateChatMessageCancel(nil, BusinessDB, groupId)
		if err != nil {
			glog.Error(err)
		}
	}
	return tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbGroup{}).Where("group_id = ? and group_type = 1", groupId).Update("state", state).Error
}

// 群 - 群成员
func (g *Group) GroupMember(gc *gin.Context, tx *gorm.DB, groupId string) (data []models.WkbGroupMember, err error) {
	// 取缓存
	redisData := make([]models.WkbGroupMember, 0)
	redisCache := redisModules.ClientRedis.Get(initParam.GroupMemberPrefix + groupId)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &redisData)
		if err != nil {
			return redisData, err
		}
		return redisData, err
	} else {
		if err != redis.Nil {
			return data, err
		}
	}
	// 查db
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbGroupMember{}).
		Table("wkb_im_group_member wgm").
		Select("wgm.group_id,if(wgm.member_type = 0,if(wud.realname is NULL,wud.nickname,wud.realname),wcs.nickname) as member_name,wgm.member_type,wud.avatar,wgm.user_id").
		Joins("inner join wkb_user_detail wud on wud.uid = wgm.user_id").
		Joins("left join wkb_im_customer_service wcs on wcs.uid = wgm.user_id AND wcs.deleted = 2").
		Where("wgm.group_id = ? and wgm.member_type <> 1", groupId).Order("wgm.member_type ASC").Scan(&data).Error
	if err != nil {
		return
	}
	if len(data) == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.GroupMemberPrefix+groupId, 3*24*time.Hour)
	return
}

// 群 - 群成员 - 修改缓存
func (g *Group) setGroupMemberCache(gc *gin.Context, tx *gorm.DB, groupId string) (data []models.WkbGroupMember, err error) {
	// 查db
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbGroupMember{}).
		Table("wkb_im_group_member wgm").
		Select("wgm.group_id,if(wgm.member_type = 0,if(wud.realname is NULL,wud.nickname,wud.realname),wcs.nickname) as member_name,wgm.member_type,wud.avatar,wgm.user_id").
		Joins("inner join wkb_user_detail wud on wud.uid = wgm.user_id").
		Joins("left join wkb_im_customer_service wcs on wcs.uid = wgm.user_id AND wcs.deleted = 2").
		Where("wgm.group_id = ? and wgm.member_type <> 1", groupId).Order("wgm.member_type ASC").Scan(&data).Error
	if err != nil {
		return
	}
	if len(data) == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.GroupMemberPrefix+groupId, 3*24*time.Hour)
	return
}

// 群 - 群成员 - 创建
func (g *Group) CreateGroupMember(gc *gin.Context, tx *gorm.DB, groupmember *models.WkbGroupMember) error {
	err := tx.SetCtx(public.GetGinTraceContext(gc)).Create(groupmember).Error
	if err == nil {
		_, err = g.setGroupMemberCache(gc, tx, groupmember.GroupID)
		if err == nil {
			return err
		}
	}
	return err
}

// 群 - 群成员 - 删除
func (g *Group) DeleteGroupMember(gc *gin.Context, tx *gorm.DB, groupId, memberId string) error {
	err := tx.SetCtx(public.GetGinTraceContext(gc)).Where("group_id = ? AND user_id = ? AND member_type > 0", groupId, memberId).Delete(&models.WkbGroupMember{}).Error
	if err == nil {
		_, err = g.setGroupMemberCache(gc, tx, groupId)
		if err == nil {
			return err
		}
	}
	return err
}

// 群 - 群成员 - 客户
func (g *Group) GroupMemberC(gc *gin.Context, tx *gorm.DB, groupId string) (data models.WkbGroupMember, err error) {
	allData, err := g.GroupMember(gc, tx, groupId)
	for _, v := range allData {
		if v.MemberType == 0 {
			data = v
		}
	}
	return
}

// 群 - 群成员 - 机器人
func (g *Group) GroupRobot(gc *gin.Context, tx *gorm.DB, groupId string) (data models.WkbImRobot, err error) {
	// 取缓存
	redisData := models.WkbImRobot{}
	redisCache := redisModules.ClientRedis.Get(initParam.GroupRobotPrefix + groupId)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &redisData)
		if err != nil {
			return
		}
		data = redisData
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	//
	userRobotMsg := &models.WkbGroupMember{}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbGroupMember{}).Where("group_id = ? and member_type = 1", groupId).Scan(userRobotMsg).Error
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImRobot{}).Where("id = ?", userRobotMsg.UserID).Scan(&data).Error
	// 存缓存
	if err != nil {
		return
	}
	if data.ID == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	err = addRedis(data, initParam.GroupRobotPrefix+groupId, 15*24*time.Hour)
	return
}

// 群 - 群成员 - 客服人员
func (g *Group) GroupMemberCs(gc *gin.Context, tx *gorm.DB, groupId string) (data []models.WkbGroupMember, err error) {
	allData, err := g.GroupMember(gc, tx, groupId)
	if err != nil {
		return
	}
	for _, v := range allData {
		if v.MemberType > 1 {
			data = append(data, v)
		}
	}
	if len(data) == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	return
}

// 群 - 群成员 - 群主管理员
func (g *Group) GroupMemberAdmin(gc *gin.Context, tx *gorm.DB, groupId string) (data models.WkbGroupMember, err error) {
	allData, err := g.GroupMember(gc, tx, groupId)
	for _, v := range allData {
		if v.MemberType == 2 {
			data = v
		}
	}
	return
}

// 群 - 群成员 - 用户为客服身份
func (g *Group) GroupMemberList(gc *gin.Context, tx *gorm.DB, userId string) (robotMsg []models.WkbGroupMember, err error) {
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbGroupMember{}).
		Table("wkb_im_group_member wgm").
		Joins("inner join wkb_im_group wg on wg.group_id = wgm.group_id").
		Select("wgm.group_id").
		Where("wgm.user_id = ? and (wgm.member_type = 3 or wgm.member_type = 4) and wg.group_type = 1", userId).Scan(&robotMsg).Error
	return
}

// 群 - 群成员 - 用户为群主身份
func (g *Group) GroupMemberAdminList(gc *gin.Context, tx *gorm.DB, userId string) (robotMsg []models.WkbGroupMember, err error) {
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbGroupMember{}).
		Select("group_id").
		Where("user_id = ? and member_type = 2", userId).Scan(&robotMsg).Error
	return
}

// 消息 - 失效
func (g *Group) UpdateChatMessageCancel(gc *gin.Context, tx *gorm.DB, extraMsg string) error {
	return tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbGroupChatMessage{}).
		Where("extra_msg = ?", extraMsg).Update("status", 4).Error
}

//通过userid查询用户
func (g *Group) GroupByName(c *gin.Context, tx *gorm.DB, groupId string, userId string) (groupMsg models.WkbGroup, err error) {
	err = tx.SetCtx(public.GetGinTraceContext(c)).Model(&models.WkbGroup{}).
		Where("group_id = ?", groupId).Scan(&groupMsg).Error
	if groupMsg.GroupType == 2 {
		err = tx.SetCtx(public.GetGinTraceContext(c)).Model(&models.WkbGroupMember{}).
			Table("wkb_im_group_member wgm").
			Select("if(ud.realname is NULL,ud.nickname,ud.realname) AS `name`,2 as group_type").
			Joins("INNER JOIN wkb_user_detail ud ON ud.uid = wgm.user_id").
			Where("wgm.group_id = ? AND user_id <> ?", groupId, userId).Scan(&groupMsg).Error
	}
	return
}
